package com.witdata.common.service.community.impl;

import com.mybatisflex.core.query.QueryWrapper;
import com.witdata.common.domain.Status;
import com.witdata.common.domain.dto.ArticleCommentDto;
import com.witdata.common.domain.dto.ArticleCommentListDto;
import com.witdata.common.domain.dto.ArticleSubCommentDto;
import com.witdata.common.exception.GlobalException;
import com.witdata.common.mapper.ArticleCommentMapper;
import com.witdata.common.service.community.ArticleCommentService;
import com.witdata.common.util.IdUtils;
import com.witdata.mysql.base.service.ArticleCommentBaseService;
import com.witdata.mysql.base.service.ArticleSubCommentBaseService;
import com.witdata.mysql.domain.entity.TArticleComment;
import com.witdata.mysql.domain.entity.TArticleSubComment;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;

/**
 * @author LiuQi
 */
@Service
@RequiredArgsConstructor
public class ArticleCommentServiceImpl implements ArticleCommentService {
    private final ArticleCommentBaseService articleCommentBaseService;
    private final ArticleSubCommentBaseService articleSubCommentBaseService;
    private final IdUtils idUtils;

    /**
     * 获取文章评论列表
     */
    @Override
    public ArticleCommentListDto getArticleCommentList(Long articleId) {
        List<TArticleComment> tArticleCommentList = articleCommentBaseService.list(new QueryWrapper().eq("article_id", articleId));
        List<ArticleCommentDto> articleCommentDtoList = ArticleCommentMapper.INSTANCE.toArticleCommentDtoList(tArticleCommentList);
        System.out.println("articleCommentDtoList = " + articleCommentDtoList);
        List<TArticleSubComment> tArticleSubCommentList = articleSubCommentBaseService.list(new QueryWrapper().eq("article_id", articleId));
        List<ArticleSubCommentDto> articleSubCommentDtoList = ArticleCommentMapper.INSTANCE.toArticleSubCommentDtoList(tArticleSubCommentList);
        System.out.println("articleSubCommentDtoList = " + articleSubCommentDtoList);
        return new ArticleCommentListDto(articleCommentDtoList, articleSubCommentDtoList);
    }

    /**
     * 发表文章评论
     */
    @Override
    public void publishArticleComment(ArticleCommentDto articleCommentDto) {
        articleCommentDto.setId(IdUtils.createId());
        articleCommentDto.setUserId(idUtils.getUserIdByRequest());
        articleCommentDto.setCreated(LocalDateTime.now());
        TArticleComment tArticleComment = ArticleCommentMapper.INSTANCE.toTArticleComment(articleCommentDto);
        articleCommentBaseService.save(tArticleComment);
    }

    /**
     * 删除文章评论
     */
    @Transactional
    @Override
    public void deleteArticleComment(Long commentId) {
        Long userId = idUtils.getUserIdByRequest();
        if (!articleCommentBaseService.exists(new QueryWrapper().eq("id", commentId).eq("user_id", userId))) {
            throw new GlobalException(Status.DELETEERROR);
        }
        deleteSecondArticleComment(Collections.singletonList(commentId));
        boolean remove = articleCommentBaseService.remove(new QueryWrapper().eq("id", commentId));
        if (!remove) throw new GlobalException(Status.DELETEERROR);
    }

    /**
     * 发表二级评论
     */
    @Override
    public void publishSecondArticleComment(ArticleSubCommentDto articleSubCommentDto) {
        articleSubCommentDto.setId(IdUtils.createId());
        articleSubCommentDto.setUserId(idUtils.getUserIdByRequest());
        articleSubCommentDto.setCreated(LocalDateTime.now());
        TArticleSubComment tArticleSubComment = ArticleCommentMapper.INSTANCE.toTArticleSubComment(articleSubCommentDto);
        articleSubCommentBaseService.save(tArticleSubComment);
    }

    @Override
    @Transactional
    public void deleteSecondArticleComment(Long commentId) {
        Long userId = idUtils.getUserIdByRequest();
        if (!articleSubCommentBaseService.exists(new QueryWrapper().eq("id", commentId).eq("user_id", userId))) {
            throw new GlobalException(Status.DELETEERROR);
        }
        deleteSecondArticleComment(Collections.singletonList(commentId));
        boolean removed = articleSubCommentBaseService.remove(new QueryWrapper().eq("id", commentId));
        if (!removed) throw new GlobalException(Status.DELETEERROR);
    }

    //递归删除二级评论
    private void deleteSecondArticleComment(List<Long> commentIds) {
        List<TArticleSubComment> articleSubComments = articleSubCommentBaseService.list();
        Map<Long, List<Long>> articleSubCommentsMaps = new HashMap<>();
        List<Long> list = new ArrayList<>();
        Queue<Long> queue = new LinkedList<>(commentIds);
        for (TArticleSubComment articleSubComment : articleSubComments) {
            List<Long> longList = articleSubCommentsMaps.get(articleSubComment.getParentCommentId());
            if (longList == null) {
                longList = new ArrayList<>();
                longList.add(articleSubComment.getId());
                articleSubCommentsMaps.put(articleSubComment.getParentCommentId(), longList);
            }else {
                longList.add(articleSubComment.getId());
            }
        }
        while (!queue.isEmpty()){
            Long poll = queue.poll();
            if (articleSubCommentsMaps.containsKey(poll)){
                List<Long> longList = articleSubCommentsMaps.get(poll);
                list.addAll(longList);
                queue.addAll(longList);
            }
        }
        boolean removed = articleSubCommentBaseService.removeByIds(list);
        if (!removed) throw new GlobalException(Status.DELETEERROR);
    }
}
